package game

import (
	"errors"
	"fmt"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/game"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
	"gorm.io/gorm"
)

//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateApi
//@description: 新增基础api
//@param: api model.SysApi
//@return: err error

type SignUpService struct{}

var SignUpServiceApp = new(SignUpService)

func (service *SignUpService) CreateSignUp(param game.BsSignUp) (err error) {
	return global.GVA_DB.Create(&param).Error
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteApi
//@description: 删除基础api
//@param: api model.SysApi
//@return: err error

func (service *SignUpService) DeleteSignUp(param game.BsSignUp) (err error) {
	var entity game.BsSignUp
	err = global.GVA_DB.First(&entity, "user_id = ? AND game_info_id = ? AND project_id = ?", param.UserId, param.GameinfoId, param.ProjectId).Error // 根据id查询api记录
	if errors.Is(err, gorm.ErrRecordNotFound) {                                                                                                      // api记录不存在
		return err
	}
	err = global.GVA_DB.Delete(&entity).Error
	if err != nil {
		return err
	}
	return nil
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetAPIInfoList
//@description: 分页获取数据,
//@param: api model.SysApi, info request.PageInfo, order string, desc bool
//@return: list interface{}, total int64, err error

// 查看国际奖牌数量
func (service *SignUpService) GetSignUpCountryOrderList(param game.BsSignUp, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{})
	var pList []game.BsSignUpStat
	db.Select("sys_users.country, COUNT(1) AS number")
	db.Joins(`
	JOIN (
		SELECT game_info_id, project_id, user_id, score
		FROM (
		SELECT 
        game_info_id, 
        project_id, 
        user_id, 
        score,
        ROW_NUMBER() OVER (PARTITION BY game_info_id, project_id ORDER BY score DESC) AS rank
		FROM bs_sign_up INNER JOIN bs_game_info on bs_game_info.id = bs_sign_up.game_info_id and bs_game_info.status = 3 ) ranked
		where rank <= 3
	) sub ON sub.user_id = sys_users.user_id
	`)
	if param.GameinfoId > 0 {
		db = db.Where("sub.game_info_id = ?", param.GameinfoId)
	}

	if param.ProjectId > 0 {
		db = db.Where("sub.project_id = ?", param.ProjectId)
	}

	err = db.Count(&total).Error

	if err != nil {
		return pList, total, err
	}

	db = db.Limit(limit).Offset(offset)
	db = db.Group("sys_users.country")
	OrderStr := "number desc"
	err = db.Order(OrderStr).Find(&pList).Error
	return pList, total, err
}

// 查看个人奖牌数量
func (service *SignUpService) GetSignUpOrderList(param game.BsSignUp, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&system.SysUser{})
	var pList []game.BsSignUpStat
	db.Select("sys_users.user_id, COUNT(1) AS number")
	db.Joins(`
	JOIN (
		SELECT game_info_id, project_id, user_id, score
		FROM (
		SELECT 
        game_info_id, 
        project_id, 
        user_id, 
        score,
        ROW_NUMBER() OVER (PARTITION BY game_info_id, project_id ORDER BY score DESC) AS rank
		FROM bs_sign_up INNER JOIN bs_game_info on bs_game_info.id = bs_sign_up.game_info_id and bs_game_info.status = 3 ) ranked
		where rank <= 3
	) sub ON sub.user_id = sys_users.user_id
	`)
	if param.GameinfoId > 0 {
		db = db.Where("sub.game_info_id = ?", param.GameinfoId)
	}

	if param.ProjectId > 0 {
		db = db.Where("sub.project_id = ?", param.ProjectId)
	}

	err = db.Count(&total).Error

	if err != nil {
		return pList, total, err
	}

	db = db.Limit(limit).Offset(offset)
	OrderStr := "number desc"
	err = db.Order(OrderStr).Find(&pList).Error
	return pList, total, err
}

func (service *SignUpService) GetSignUpList(param game.BsSignUp, info request.PageInfo, order string, desc bool) (list interface{}, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&game.BsSignUp{})
	var pList []game.BsSignUp

	if param.GameinfoId > 0 {
		db = db.Where("game_info_id = ?", param.GameinfoId)
	}

	if param.ProjectId > 0 {
		db = db.Where("project_id = ?", param.ProjectId)
	}

	if param.Status > 0 {
		db = db.Where("status = ?", param.Status)
	}

	err = db.Count(&total).Error

	if err != nil {
		return pList, total, err
	}

	db = db.Limit(limit).Offset(offset)
	OrderStr := "id desc"
	if order != "" {
		orderMap := make(map[string]bool, 5)
		orderMap["id"] = true
		orderMap["update_time"] = true
		orderMap["create_time"] = true
		if !orderMap[order] {
			err = fmt.Errorf("非法的排序字段: %v", order)
			return pList, total, err
		}
		OrderStr = order
		if desc {
			OrderStr = order + " desc"
		}
	}
	err = db.Order(OrderStr).Find(&pList).Error
	return pList, total, err
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetApiById
//@description: 根据id获取api
//@param: id float64
//@return: api model.SysApi, err error

func (service *SignUpService) GetSignUp(userId, groupInfoId, projectId int) (res game.BsSignUp, err error) {
	err = global.GVA_DB.First(&res, "user_id = ? AND group_info_id = ? AND project_id = ?", userId, groupInfoId, projectId).Error
	return
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: UpdateApi
//@description: 根据id更新api
//@param: api model.SysApi
//@return: err error

func (service *SignUpService) UpdateSignUp(p game.BsSignUp) (err error) {
	return global.GVA_DB.Save(&p).Error
}
